//! 客户端
use super::gap::{adv, ConnReceiver};
use super::gatt::{self, ConnDaemon, DataChannel};
use crate::common::thread;
use alloc::boxed::Box;
use eds::Writer;
use nrf_softdevice::ble::Connection as BleConn;
use unmp_link::prelude::*;

pub struct Conn {
    writer: Writer,
    ch: DataChannel,
}
impl Conn {
    async fn new(conn: BleConn) -> Self {
        let (daemon, ch) = ConnDaemon::new(conn);
        thread::spawn(gatt::daemon_conn(daemon));
        Self {
            writer: Writer::new(3),
            ch,
        }
    }
}
#[async_trait]
impl ConnectionDriver for Conn {
    fn kind(&self) -> &str {
        "ble_client"
    }
    fn id(&self) -> &str {
        ""
    }
    fn get_send_buf(&mut self) -> Option<BytesMut> {
        self.writer.get_load()
    }
    async fn send(&mut self, buf: BytesMut) -> Result<(), SendError> {
        let data = self.writer.get_data(buf);

        self.ch.tx.send(Bytes::copy_from_slice(data)).await;
        Ok(())
    }
    async fn recv(&mut self) -> Result<Bytes, RecvError> {
        let data = self.ch.rx.recv().await;
        if data.len() == 0 {
            return Err(RecvError::Disconnected);
        }
        Ok(data)
    }
}

pub struct Client {
    conn_rx: ConnReceiver,
}
impl Client {
    pub fn new() -> Listener {
        let conn_rx = adv::start_adv();
        Listener::new(Box::new(Self { conn_rx }))
    }
}
#[async_trait]
impl ListenerDriver for Client {
    fn kind(&self) -> &str {
        "ble_client"
    }
    fn id(&self) -> &str {
        ""
    }
    async fn accept(&mut self) -> Result<Connection, RecvError> {
        let conn = self.conn_rx.recv().await;
        let conn = Conn::new(conn).await;
        Ok(Connection::new(Box::new(conn)))
    }
}
